package accounts

import (
	"errors"
	"gitee.com/slion/account/services"
	"gitee.com/slion/infra/base"
	"github.com/sirupsen/logrus"
	"gopkg.in/go-playground/validator.v9"
)

// 应用服务层

type accountService struct {}

// 实例化接口,需要实现接口定义的方法
var AccountService services.AccountService = new(accountService)

// 初始化方法里,实例化accountService并赋值给services.IAccountService
func init(){
	services.IAccountService = new(accountService)
}

func (a *accountService) CreateAccount(dto services.AccountCreateDTO) (*services.AccountDTO, error) {

	domain := DomainAccount{}
	// 验证输入参数
	err := base.Validate().Struct(&dto)
	if err != nil {
		_, ok := err.(*validator.InvalidValidationError)
		if ok {
			logrus.Error("验证错误", err)
		}
		errs, ok := err.(validator.ValidationErrors)
		if ok {
			for _, e := range errs {
				logrus.Error(e.Translate(base.Translator()))
			}
		}
		return nil, err
	}

	// 执行账户创建逻辑
	accountDto := &services.AccountDTO{
		AccountCreateDTO: services.AccountCreateDTO{
			UserId:       dto.UserId,
			Username:     dto.Username,
			AccountName:  dto.AccountName,
			AccountType:  dto.AccountType,
			CurrencyCode: dto.CurrencyCode,
		},
		Balance:          dto.Amount,
		Status:           1,
	}
	return domain.Create(accountDto)
}

func (a *accountService) Transfer(dto services.AccountTransferDTO) (services.TransferStatus, error) {

	domain := DomainAccount{}

	// 验证输入参数
	err := base.Validate().Struct(&dto)
	if err != nil {
		_, ok := err.(*validator.InvalidValidationError)
		if ok {
			logrus.Error("验证错误", err)
		}
		errs, ok := err.(validator.ValidationErrors)
		if ok {
			for _, e := range errs {
				logrus.Error(e.Translate(base.Translator()))
			}
		}
		return services.TransferStatusFailure, err
	}

	// 执行转账
	// change_type 流水交易类型 0:创建账户 1:收入 -1:支出
	// change_flag 交易变化标识 -1出账 1进账
	if dto.ChangeFlag == services.FlagExpenditure { // 支出
		if dto.ChangeType > 0 {
			return services.TransferStatusFailure, errors.New("如果ChangeFlag为支出,那么ChangeType必须小于0")
		}
	} else { // 收入
		if dto.ChangeType < 0 {
			return services.TransferStatusFailure, errors.New("如果ChangeFlag为收入,那么ChangeType必须大于0")
		}
	}
	return domain.Transfer(dto)
}

func (a *accountService) StoreValue(dto services.AccountTransferDTO) (services.TransferStatus, error) {

	// 交易主体和交易目标都是自己
	dto.TradeTarget = dto.TradeBody
	// 交易类型为进账
	dto.ChangeType = services.AccountStoreValue
	// 交易标识为收入
	dto.ChangeFlag = services.FlagIncome
	return a.Transfer(dto)
}

func (a *accountService) GetEnvelopesAccountByUserId(userId string) *services.AccountDTO {
	domain := DomainAccount{}
	return domain.GetAccountByUserId(userId, int(services.EnvelopeAccount))
}

func (a *accountService) GetAccount(accountNo string) *services.AccountDTO {
	domain := DomainAccount{}
	return domain.GetAccount(accountNo)
}

